﻿// controller for the main search screen
angular.module('app.search').controller('SearchController', ['$scope', '$state', 'uploadService', 'dataService', 'notify',
	function ($scope, $state, uploadService, dataService, notify) {
		'use strict';

		var instance = this,
	        selectedPatternId = -1,
			// convert rgb to hex value
			hexFromRGB = function (r, g, b) {
				var hex = [r.toString(16), g.toString(16), b.toString(16)];
				angular.forEach(hex, function (value, key) {
					if (value.length === 1) hex[key] = "0" + value;
				});
				return hex.join('').toUpperCase();
			};
		// stop the timer
		$scope.$broadcast('timer-stop');
		// search models for image, color, and pattern
		$scope.model = {
			// search by image midel
			byImage: {
				isAnalyzing: false,
				uploadedImageId: -1,
				startAnalysis: function (uploadedId) {
					// image was uploaded, start the time to wait until processing should be done
					$scope.model.byImage.uploadedImageId = uploadedId;
					$scope.$broadcast('timer-start');
					$scope.model.byImage.isAnalyzing = true;
				},
				uploadFiles: [],
				message: '',
				search: function () {
					// get the uploaded files
					var files = $scope.model.byImage.uploadFiles;
					// require one to uploaded
					if (files.length < 1) {
						$scope.model.byImage.message = 'Please select an image to upload';
						return;
					}

					// notify upload in progress
					notify.info('Uploading...');
					// add file to form data
					var fd = new FormData();
					fd.append("file", files[0]);
					// send the file to the upload service
					uploadService.upload(fd).then(instance.viewByImageSearchResults);
				}
			},
			// search by pattern
			byPattern: {
				groups: [],
				message: 'Loading patterns...',
				// check if the pattern is selected
				isSelected: function (patternId) {
					return (instance.selectedPatternId !== undefined &&
                            instance.selectedPatternId !== null &&
                            instance.selectedPatternId === patternId) ? 'selected' : '';
				},
				select: function (patternId) {
					// set the pattern as the selected pattern
					instance.selectedPatternId = patternId;
				},
				// search by pattern function which goes to search results by pattern state
				search: function () {
					$state.transitionTo('search-results.by-pattern', { tolerance: 90, patternId: instance.selectedPatternId });
				}
			},
			// search by color model
			byColor: {
				// list of color pickers
				colorpickers: [],
				// adds a new color picker
				addColorPicker: function () {
					// default picker values
					var picker = {
						red: 0,
						green: 0,
						blue: 0,
						tolerance: 25,
						percent: 50,
						swatchStyle: { 'background-color': '#000000' },
						colorOptions: {
							orientation: 'horizontal',
							min: 0,
							max: 255,
							range: 'min'
						},
						toleranceOptions: {
							orientation: 'horizontal',
							min: 0,
							max: 50,
							range: 'min'
						}
					},
					// changes the color of the swatch or square
					refreshSwatch = function () {
						picker.swatchStyle['background-color'] = '#' + hexFromRGB(picker.red, picker.green, picker.blue);
					};
					// when the change event is raised, refresh the color
					picker.colorOptions.change = refreshSwatch;
					// when the slide is moved, refresh the color
					picker.colorOptions.slide = refreshSwatch;
					// add the new color picker
					$scope.model.byColor.colorpickers.push(picker);
				},
				// search call
				search: function () {
					var asStrings = [];
					// build the search string
					angular.forEach($scope.model.byColor.colorpickers, function (picker) {
						asStrings.push('[' + hexFromRGB(picker.red, picker.green, picker.blue) + ',' + picker.percent + ',' + picker.tolerance +  ']');
					});
					// go to the search by color results
					$state.transitionTo('search-results.by-color', { colors: encodeURIComponent(asStrings.join(';')) });
				}
			}
		};

		// when the time is stopped
		$scope.$on('timer-stopped', function () {
			// if analyzing, go to the results page
			if ($scope.model.byImage.isAnalyzing) {
				$state.transitionTo('search-results.by-image', { tolerance: 10, imageId: $scope.model.byImage.uploadedImageId });
			}
		});
		// search by image upload result handler
		this.viewByImageSearchResults = function (uploadReply) {
			var data = uploadReply.data;
			if (data === null || data === undefined || data.length < 1) {
				return;
			}
			// get the upload response
			var uploadedImageResponse = data[0];
			// if the upload failed or nothing was uploaded, return
			if (!uploadedImageResponse.Successful ||
				uploadedImageResponse.Content === null ||
				uploadedImageResponse.Content === undefined) {
				return;
			}
			// start the timer to wait for the analysis to complete
			$scope.model.byImage.startAnalysis(uploadedImageResponse.Content.Id);
		};

		// handler for when the download of patterns is completed
		this.handleDownloadPatternsReply = function (response) {
			if (response.data.Successful && response.data.Content.length > 0) {
				// clear the message and set the pattern description groups
				$scope.model.byPattern.message = '';
				$scope.model.byPattern.groups = response.data.Content;
			}
		};

		// add the first color picker
		$scope.model.byColor.addColorPicker();
		// download the pattern descriptions
		return dataService.download('PatternDescriptionGroup', '').then(instance.handleDownloadPatternsReply);
	}]);